<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <canvas id="canvas" width=400 height=400></canvas>
</body>
</html>
<script>
   /** @type {HTMLCanvasElement} */
   let canvas = document.getElementById('canvas');
  let gl = canvas.getContext('webgl');
  gl.clearColor(0.1, 0.5, 0.4, 0.3);
  gl.clear(gl.COLOR_BUFFER_BIT);

  function initShader(gl, vertexSource, fragmentSource) {
    // 创造着色器对象
    let vertexShader = gl.createShader(gl.VERTEX_SHADER);
    let fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
    gl.shaderSource(vertexShader, vertexSource);
    gl.shaderSource(fragmentShader, fragmentSource)
    gl.compileShader(vertexShader);
    gl.compileShader(fragmentShader);
    let program = gl.createProgram();
    gl.attachShader(program, vertexShader)
    gl.attachShader(program, fragmentShader)
    gl.linkProgram(program);
    gl.useProgram(program);
    return program
  }
  
  let vertexSource = `
    //attribute声明vec4类型变量position
    attribute vec4 position;
    // attribute声明顶点颜色变量
    attribute vec4 color;
    //varying声明顶点颜色插值后变量
    varying vec4 vv_color;
    void main() {
      // 顶点坐标position赋值给内置变量gl_Position
      float r = radians(30.0);
      float cos = cos(r);
      float sin = sin(r);
      // 绕x旋转
      mat4 mx = mat4(1,0,0,0, 0,cos,-sin,0, 0,sin,cos,0, 0,0,0,1);
      // 绕y旋转
      mat4 my = mat4(cos,0,-sin,0, 0,1,0,0, sin,0,cos,0, 0,0,0,1);
      // 绕z旋转
      mat4 mz = mat4(cos,sin,0,0, -sin,cos,0,0, 0,0,1,0, 0,0,0,1);
      gl_Position = mx*my*position;
      //顶点颜色插值计算
      vv_color = color;
    }
  `
  let fragmentSource = `
    // 所有float类型数据的精度是lowp  lowp   ：精确度低;mediump：精确度中;highp  ：精确度高
    precision lowp float;
    // 接收顶点着色器中v_color数据
    varying vec4 vv_color;
    void main() {
      // 插值后颜色数据赋值给对应的片元
      gl_FragColor = vv_color;
    }
  `
  let program = initShader(gl, vertexSource, fragmentSource);
  let position = gl.getAttribLocation(program,'position');
  let color = gl.getAttribLocation(program,'color');

  /**
  创建顶点位置数据数组data,Javascript中小数点前面的0可以省略
  **/
  var data=new Float32Array([
      .5,.5,.5,-.5,.5,.5,-.5,-.5,.5,.5,.5,.5,-.5,-.5,.5,.5,-.5,.5,      //面1
      .5,.5,.5,.5,-.5,.5,.5,-.5,-.5,.5,.5,.5,.5,-.5,-.5,.5,.5,-.5,      //面2
      .5,.5,.5,.5,.5,-.5,-.5,.5,-.5,.5,.5,.5,-.5,.5,-.5,-.5,.5,.5,      //面3
      -.5,.5,.5,-.5,.5,-.5,-.5,-.5,-.5,-.5,.5,.5,-.5,-.5,-.5,-.5,-.5,.5,//面4
      -.5,-.5,-.5,.5,-.5,-.5,.5,-.5,.5,-.5,-.5,-.5,.5,-.5,.5,-.5,-.5,.5,//面5
      .5,-.5,-.5,-.5,-.5,-.5,-.5,.5,-.5,.5,-.5,-.5,-.5,.5,-.5,.5,.5,-.5 //面6
  ]);


  /**
 创建顶点颜色数组colorData
 **/
var colorData = new Float32Array([
    1,0,0, 1,0,0, 1,0,0, 1,0,0, 1,0,0, 1,0,0,//红色——面1
    0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,//绿色——面2
    0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,//蓝色——面3
    1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,//黄色——面4
    0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0,//黑色——面5
    1,1,1, 1,1,1, 1,1,1, 1,1,1, 1,1,1, 1,1,1 //白色——面6
]);

let buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER,buffer);
gl.bufferData(gl.ARRAY_BUFFER,data,gl.STATIC_DRAW);
gl.vertexAttribPointer(position,3,gl.FLOAT,false,0,0);
gl.enableVertexAttribArray(position);


let colorBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER,colorBuffer);
gl.bufferData(gl.ARRAY_BUFFER,colorData,gl.STATIC_DRAW);
gl.vertexAttribPointer(color,3,gl.FLOAT,false,0,0);
gl.enableVertexAttribArray(color);

gl.enable(gl.DEPTH_TEST);// 
gl.drawArrays(gl.TRIANGLES,0,36)
</script>